package concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 异步处理，callable类似runnable，还可以有返回值和异常处理
 * 需要包装在实现了Runnable和Future的FutureTask中，作为FutureTask的target
 * 多个实例共享Thread成员变量*
 */
public class CallableFutureTask3 implements Callable<String> {
    private int myCounter = 0;

    public String call() {
        for (; myCounter < 20; myCounter++) {
            if (Thread.currentThread().getName().equals("return1")) {
                System.out.println("\t\t" + Thread.currentThread().getName() + "  " + myCounter);
            } else {
                System.out.println("\t" + Thread.currentThread().getName() + "  " + myCounter);
            }
        }
        // call()方法可以有返回值
        return Thread.currentThread().getName() + " finished!";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建Callable对象
        CallableFutureTask3 rt = new CallableFutureTask3();

        //同一个target被传给了两个不同的FutureTask对象，这两个task对象又被传给了两个线程，他们同享myCounter变量
        FutureTask<String> task = new FutureTask<String>(rt);
        FutureTask<String> task2 = new FutureTask<String>(rt);

        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + "主线程输出：" + i);
            if (i == 1) {
                // 实质还是以Runnable对象来创建、并启动线程
                new Thread(task, "return1").start();
                new Thread(task2, "return2").start();
//                //下面这样不管用！
//                new Thread(task, "return2").start();
            }
        }
        try {
            // 获取线程返回值
            System.out.println("主线程的返回值：" + task.get());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}